/*
 *  MapScene.cpp
 *  SpaceTrader
 *
 *  Created by Andrew on 10/16/12.
 *  Copyright 2012 The Hex Pistols. All rights reserved.
 *
 */

#include "MapScene.h"
#include "GuiButton.h"
#include "Universe.h"
#include <vector>
#include <iostream>
#include <sstream>

MapScene::MapScene(Universe *universe) : universe(universe), nextPlanet(NULL), travelManager(new TravelManager()), nextDistance(0) { }

MapScene::~MapScene(){
    free(universe);
    free(nextPlanet);
    free(travelManager);
}

MapScene::MapScene(const MapScene &M) : universe(M.universe), nextPlanet(M.nextPlanet),
                                            travelManager(M.travelManager),
                                            nextDistance(M.nextDistance) { }

MapScene& MapScene::operator=(const MapScene &M){
    // check for "self assignment" and do nothing in that case
    if (this == &M) return *this;
    else {
        delete universe;
        delete nextPlanet;
        delete travelManager;
        universe = M.universe;
        nextPlanet = M.nextPlanet;
        travelManager = M.travelManager;
        return *this;
    }
}
/*
 * TODO: check for memory leaks
 * draws the scene and handles its logic
 * and user input
 */
state_t MapScene::draw(SDL_Surface *screen, Planet *playersLocation, int playersFuel) {
	
	state_t next_state = MAP;
	
	TTF_Font *buttonFont = TTF_OpenFont( "Futura.ttc", 20 );
	
	const int boxW = 260, boxH = 105;
	SDL_Surface *background = load_image("galaxy.png", false);
	SDL_Surface *background1 = load_image("starfield.png",false);
	/*Uint32 boxColor = SDL_MapRGBA(screen->format, 0xaa, 0xaa, 0xaa, 0x10);
	SDL_Rect infoBox;
	infoBox.x = 0;
	infoBox.y = 0;
	infoBox.w = boxW;
	infoBox.h = boxH;
	*/
	SDL_Surface *infoBox = load_image("infoBox.png",false);
	int infoX = 0, infoY = 0;

	
	GuiTable systemInfo(5,2,0,0,85,20,16);
	GuiTable planetInfo(5,2,0,0,100,20,16);
	
	SDL_Event event;
	
	std::vector<GuiButton*> systemButtons;
	std::vector<GuiButton*> planetButtons;
	std::vector<System*> systems = universe->getSystems();
	std::vector<Planet*> planets;
	GuiButton backButton(0,0,"", "Back");
	
	bool systemView = true; //which system is being viewed, -1 for no system
	int currSystem = -1; //which system/planet is being hovered over, -1 for no system/planet
	int currPlanet = -1; 
	//int prevSystem = -1; //used to determine if a new table needs to be made (slight optimization)
	int prevPlanet = -1;
	button_state_t buttonState = NONE;
	
	for (unsigned int i = 0; i < systems.size(); i++) {
		systemButtons.push_back(new GuiButton(systems[i]->getX(), systems[i]->getY(), "", systems[i]->getName()));
	}
	
	while (next_state==MAP) {
		
		//Event Loop
		while (SDL_PollEvent(&event)) {
			//viewing the systems
			if (systemView == true) {
				currSystem = -1; //resets which system is hovered over (easiest way of covering the "not over any buttons" case)
				for (unsigned int i = 0; i < systems.size(); i++) {
					//looping through each system's corresponding button
					if ((buttonState = systemButtons[i]->handle_input(event)) == CLICKED) {
						systemView = false;
						for (unsigned int j = 0; j < planetButtons.size(); j ++) {
							free(planetButtons[j]);
						}
						planetButtons.clear(); 
						planets = systems[i]->getPlanets();
						for (unsigned int j = 0; j < planets.size(); j++) {
							planetButtons.push_back(new GuiButton(planets[j]->getX(), planets[j]->getY(), "", planets[j]->getName()));
                            if (planets[i]->getName() == playersLocation->getName()){
                                planetButtons[i]->setState(2);
                            }
						}
					}
					else if (buttonState == MOUSEOVER) currSystem = i;
				}
				if (backButton.handle_input(event) == CLICKED) next_state = PLANET;
			}
			//looping through the specified system's planets
			else {
				currPlanet = -1;
				for (unsigned int i = 0; i < planetButtons.size(); i++) {
					if ((buttonState = planetButtons[i]->handle_input(event)) == CLICKED) {
						//cout << playersLocation.getX();
                        if (travelManager->getDistance(playersLocation, planets[i], universe) <= playersFuel
                                && travelManager->getDistance(playersLocation, planets[i], universe) > 0){
                            nextPlanet = planets[i];
							nextDistance = travelManager->getDistance(playersLocation, planets[i], universe);
                            next_state = TRAVEL;
						}
					}
					if (buttonState == MOUSEOVER) currPlanet = i;
				}
				if (backButton.handle_input(event) == CLICKED) systemView = true;
			}
			if (event.type==SDL_QUIT) next_state = QUIT;
			
			//show objects
			if (systemView == true) {
				apply_surface(0, 0, background, screen);
				backButton.show(screen);
				for (unsigned int i = 0; i < systemButtons.size(); i++) {
					systemButtons[i]->show(screen);
				}
				/*
				 if (currSystem != -1) {
				 
				 if (prevSystem != currSystem ) {
				 const char[]* info = {"Name: ".c_str(), systems[currSystem]->name, systems[currSystem]->
				 infoTable.setContents()
				 }
				 SDL_FillRect(screen, infoBox, gray);
				 
				 }
				 */
				
			} else {
				apply_surface( 0, 0, background1, screen );


				backButton.show(screen);
				for (unsigned int i = 0; i < planetButtons.size(); i++) {
                    if(planets[i]->getName() == playersLocation->getName()){
                        planetButtons[i]->setState(2);
                    }
					planetButtons[i]->show(screen);
				}
				
				if (currPlanet != -1) {
					if (prevPlanet != currPlanet) {
						prevPlanet = currPlanet;
                        std::stringstream dist;
                        int distance = 0;
                        if (playersLocation != NULL) {
                            dist << travelManager->getDistance(playersLocation, planets[currPlanet], universe);
                            distance = travelManager->getDistance(playersLocation, planets[currPlanet], universe);
                            if (distance == 0){
                                dist.str("");
                                dist.clear();
                                dist << "You are here";
                            }
							//std::cout << dist.str().c_str() << std::endl;
                        } else {
                            dist << "N/A";
                            distance = -1;
                        }
						//Pointers were getting overwritten?
						/*const char *info[] = {"Name", "Tech Level: ","Resources: ","Distance: ", //the blank will be filled with the current effects later
							planets[currPlanet]->getName().c_str(),
							planets[currPlanet]->techLevelToString(),
							planets[currPlanet]->resourcesLevelToString(), 
							dist.str().c_str()
						};*/
						std::vector<std::string> info;
						info.push_back("Name: ");
						info.push_back("Tech Level: ");
						info.push_back("Resources: ");
						info.push_back("Distance: ");
						info.push_back("Event: ");
						info.push_back(planets[currPlanet]->getName());
						info.push_back(planets[currPlanet]->techLevelToString());
						info.push_back(planets[currPlanet]->resourcesLevelToString());
						//checks distance against current fuel and sets formatting code
						info.push_back(distance > playersFuel ? std::string("|r"+dist.str()) : dist.str());
						info.push_back(planets[currPlanet]->worldEventToString());

						
						
						planetInfo.setContents(info);
					}
					if (screen->w - boxW - 10 < event.button.x) { //the 10 is so the mouse doesn't cover the box
						infoX = event.button.x - boxW;
						planetInfo.setX(event.button.x - boxW + 9);
					}
					else {
						infoX = event.button.x + 10;
						planetInfo.setX(event.button.x + 19);
					}
					if (screen->h - boxH < event.button.y) {
						infoY = event.button.y - boxH;
						planetInfo.setY(event.button.y - boxH);
					}
					else {
						infoY = event.button.y;
						planetInfo.setY(event.button.y);
					}
					apply_surface(infoX, infoY, infoBox, screen);
					//SDL_FillRect(screen, &infoBox, boxColor);
					planetInfo.show(screen);
				}
			}
			
			if ( SDL_Flip( screen ) == -1 ) {
				std::cerr << "Error Updating screen." << std::endl;
			}
			if(SDL_GetTicks() < 1000 / FPS)
				SDL_Delay((1000/FPS)-SDL_GetTicks());
		}
	}
	for (unsigned int i = 0; i < planetButtons.size(); i ++) {
		free(planetButtons[i]);
	}
	planetButtons.clear();
	for (unsigned int i = 0; i < systemButtons.size(); i ++) {
		free(systemButtons[i]);
	}
	systemButtons.clear();
	SDL_FreeSurface(background);
	SDL_FreeSurface(background1);
	TTF_CloseFont(buttonFont);
	return next_state;
}

Planet *MapScene::getPlanet(){
    return nextPlanet;
}

int MapScene::getDistance()
{
	return nextDistance;
}
